package controllers;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import repository.EventRepository;
import repository.SearchRepository;
import repository.UserRepository;
import repository.WorkPostRepository;
import util.EmailSender;
import util.MailTitleBody;
import validator.EmailFormValidator;
import validator.EventFormValidator;
import validator.WorkPostFormValidator;

import command.EmailForm;
import command.EventForm;
import command.WorkPostForm;

import domain.Event;
import domain.User;
import domain.WorkPost;

@Controller
public class NotificationController {

	private UserRepository userRepository;
	private SearchRepository searchRepository;
	private EventRepository eventRepository;
	private WorkPostRepository workPostRepository;
	private EmailFormValidator emailFormValidator;
	private EventFormValidator eventFormValidator;
	private WorkPostFormValidator workPostFormValidator;
	private MessageSource msgSrc; 

	@Autowired
	public NotificationController(UserRepository userRepository,
			SearchRepository searchRepository,
			EventRepository eventRepository,
			WorkPostRepository workPostRepository,
			EmailFormValidator emailFormValidator,
			EventFormValidator eventFormValidator,
			WorkPostFormValidator workPostFormValidator,
			MessageSource msgSrc) {
		this.userRepository = userRepository;
		this.searchRepository = searchRepository;
		this.eventRepository = eventRepository;
		this.workPostRepository = workPostRepository;
		this.emailFormValidator = emailFormValidator;
		this.eventFormValidator = eventFormValidator;
		this.workPostFormValidator = workPostFormValidator;
		this.msgSrc = msgSrc; 
	}

	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView SendEmail() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("users", userRepository.getRegisteredUsers());
		mav.addObject("emailForm", new EmailForm());
		mav.setViewName("notification/SendEmail");
		return mav;
	}

	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView SendEmail(HttpSession session, EmailForm emailForm, Errors errors) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("users", userRepository.getRegisteredUsers());
		mav.addObject("emailForm", new EmailForm());
		mav.setViewName("notification/SendEmail");
		emailFormValidator.validate(emailForm, errors);
		if (errors.hasErrors()) {
			return mav;
		}
		new EmailSender(emailForm.getFrom(), emailForm.getTo(), new MailTitleBody(emailForm.getSubject(), emailForm.getBody().replace("\n", "<br />"))).start();
		mav.addObject("messages", msgSrc.getMessage("emailEnviado", null,null));
		return mav;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView NewWorkPost(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("users", userRepository.getRegisteredUsers());
		mav.addObject("profiles", searchRepository.getSavedResultsByUser((User)session.getAttribute("user")));
		mav.addObject("workPostForm", new WorkPostForm());
		mav.setViewName("notification/NewWorkPost");
		return mav;
	}

	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView NewWorkPost(HttpSession session, WorkPostForm workPostForm, Errors errors) {
		ModelAndView mav = new ModelAndView();
		workPostFormValidator.validate(workPostForm, errors);
		if (errors.hasErrors()) {
			mav.addObject("users", userRepository.getRegisteredUsers());
			mav.addObject("profiles", searchRepository.getSavedResultsByUser((User)session.getAttribute("user")));
			return mav;
		}
		User loggedUser = (User)session.getAttribute("user");
		WorkPost workPost = new WorkPost(loggedUser, workPostForm.getTitle(), workPostForm.getStart(), 
				workPostForm.getHours(), workPostForm.getDescription());
		workPost.setUsersInvited(workPostForm.getToUsers());
		workPost.addSearchProfiles(workPostForm.getToProfiles());
		this.workPostRepository.save(workPost);
		for (User user: workPost.getUsersInvited()) {
			user.addWorkPostNotification(workPost);
		}
		return viewWorkPost(session, workPost);
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView viewWorkPosts(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		User user = (User)session.getAttribute("user");
		List<WorkPost> workPosts = workPostRepository.getWorkPostsByUser(user);
		mav.addObject("workPosts", workPosts);
		mav.setViewName("notification/viewWorkPosts");
		return mav;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView viewWorkPost(HttpSession session, @RequestParam("work_post_id") WorkPost workPost) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("userlogged", (User)session.getAttribute("user"));
		mav.addObject("workPost", workPost);
		mav.setViewName("notification/WorkPost");
		return mav;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView deleteWorkPost(HttpSession session, @RequestParam("work_post_id") WorkPost workPost) {
		List<User> users = userRepository.getRegisteredUsers();
		for (User user: users) {
			user.removeWorkPostNotification(workPost);
		}
		//TODO: esto no anda
		workPostRepository.delete(workPost);
		return viewWorkPosts(session);
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public String removeWorkPostNotification(HttpSession session, @RequestParam("work_post_id") WorkPost workPost) {
		User user = (User)session.getAttribute("user");
		user = userRepository.getUserByDocNumber(user.getDocNumber());
		user.removeWorkPostNotification(workPost);
		session.setAttribute("user", user);
		return "redirect:../general/index";
	}
	
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView NewEvent(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("users", userRepository.getRegisteredUsers());
		mav.addObject("profiles", searchRepository.getSavedResultsByUser((User)session.getAttribute("user")));
		mav.addObject("eventForm", new EventForm());
		mav.setViewName("notification/NewEvent");
		return mav;
	}

	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView NewEvent(HttpSession session, EventForm eventForm, Errors errors) {
		ModelAndView mav = new ModelAndView();
		eventFormValidator.validate(eventForm, errors);
		if (errors.hasErrors()) {
			mav.addObject("users", userRepository.getRegisteredUsers());
			mav.addObject("profiles", searchRepository.getSavedResultsByUser((User)session.getAttribute("user")));
			return mav;
		}
		User loggedUser = (User)session.getAttribute("user");
		Event event = new Event(loggedUser, eventForm.getName(), eventForm.getDate(), 
				eventForm.getLocation(), eventForm.getDescription());
		event.setUsersInvited(eventForm.getToUsers());
		event.addSearchProfiles(eventForm.getToProfiles());
		this.eventRepository.save(event);
		List<User> usersInvited = event.getUsersInvited();
		String[] emails = new String[usersInvited.size()];
		int i=0;
		for (User user: usersInvited) {
			user.addEventNotification(event);
			emails[i++] = user.getEmail();
		}
		new EmailSender(emails, new MailTitleBody("Tiene una invitaci&oacute;n a un evento", event.toString())).start();
		return viewEvent(session, event);
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView viewEvents(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		User user = (User)session.getAttribute("user");
		List<Event> events = eventRepository.getEventsByUser(user);
		mav.addObject("events", events);
		mav.setViewName("notification/viewEvents");
		return mav;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView viewEvent(HttpSession session, @RequestParam("event_id") Event event) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("userlogged", (User)session.getAttribute("user"));
		mav.addObject("event", event);
		mav.setViewName("notification/Event");
		return mav;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView deleteEvent(HttpSession session, @RequestParam("event_id") Event event) {
		List<User> users = userRepository.getRegisteredUsers();
		for (User user: users) {
			user.removeEventNotification(event);
		}
		//TODO: esto no anda
		eventRepository.delete(event);
		return viewEvents(session);
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public String removeEventNotification(HttpSession session, @RequestParam("event_id") Event event) {
		User user = (User)session.getAttribute("user");
		user = userRepository.getUserByDocNumber(user.getDocNumber());
		user.removeEventNotification(event);
		session.setAttribute("user", user);
		return "redirect:../general/index";
	}
}
